package com.ace.explore.starter.config;

import com.ace.explore.starter.advisor.RequestBodyAdvisor;
import com.ace.explore.starter.advisor.ResponseBodyAdvisor;
import com.ace.explore.starter.interceptor.DefaultHandlerInterceptor;
import com.google.common.collect.Lists;
import convert.StringDateConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by ace on 2017/6/27.
 */
@Configuration
@ConditionalOnWebApplication
public class WebMvcConfiguration extends DelegatingWebMvcConfiguration {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/",
            "classpath:/resources/",
            "classpath:/static/",
            "classpath:/public/"
    };


    @Override
    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
        RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
        adapter.setRequestBodyAdvice(Lists.newArrayList(new RequestBodyAdvisor()));
        adapter.setResponseBodyAdvice(Lists.newArrayList(new ResponseBodyAdvisor()));
        return adapter;
    }

    @Override
    @Autowired(required = false)
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
        if (configurers == null) {
            configurers = new ArrayList<>();
        }
        configurers.add(webMvcConfigurer());
        super.setConfigurers(configurers);
    }

    @Bean
    public HandlerInterceptor defaultHandlerInterceptor() {
        return new DefaultHandlerInterceptor();
    }


    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                super.addInterceptors(registry);
            }

            @Override
            public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
                super.configureHandlerExceptionResolvers(exceptionResolvers);
            }

            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                super.addResourceHandlers(registry);
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/", "classpath:/webjars/");
                }
                if (!registry.hasMappingForPattern("/**")) {
                    registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
                }
                registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
                registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/");
                registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");
            }

            @Override
            public void addFormatters(FormatterRegistry registry) {
                super.addFormatters(registry);
                registry.addConverter(new StringDateConvert());
            }

            @Override
            public void addCorsMappings(CorsRegistry registry) {
                super.addCorsMappings(registry);
                registry.addMapping("/**")
                        .allowedOrigins("*")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowCredentials(true);
            }


        };
    }
}
